/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Actors;


import ElementsProperties.Killable;
import ElementsProperties.Jumpable;
import ElementsProperties.Deviable;
import ElementsProperties.Drownable;
import Model.ActorEvent;
import Model.ActorListener;


import ElementsProperties.Explodable;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import EnigmaUtils.ImageLoader;

/**
 *
 * @author Snowangelic
 */
public class HumanControlledBall extends BouncableActor implements Drownable,Killable,Explodable,Jumpable,Deviable {

    private long invincibility;//Temps restant d'invincibilité
    private long jumping;
    private int currentJumpingImg;
    private long jumpingTime;
    private long timeByJumpingImg;
    private BufferedImage[] invincibleImgs;
    private BufferedImage[] jumpImgs;
    private BufferedImage imageBackup;
    private double userImpulseFactor;
    private boolean jumpEnabled;

    public HumanControlledBall(){
        super();
        image=ImageLoader.loadImage("./images/fg-blackball.png").getSubimage(0, 0, 40, 40);

        setUserImpulseFactor(1);

        invincibility=0;
        jumping=0;
        jumpEnabled=true;
        currentJumpingImg=0;
        jumpingTime=400;
        timeByJumpingImg=jumpingTime/8;

        invincibleImgs = new BufferedImage[3];
        BufferedImage imgTemp1 = EnigmaUtils.ImageLoader.loadImage("./images/halo.png");
        BufferedImage imgTemp2 = EnigmaUtils.ImageLoader.loadImage("./images/halo-blink.png");
        invincibleImgs[0] = imgTemp1.getSubimage(0, 0, 40, 40);
        invincibleImgs[1] = imgTemp2.getSubimage(0, 0, 40, 40);
        invincibleImgs[2] = imgTemp2.getSubimage(0, 40, 40, 40);

        jumpImgs = new BufferedImage[5];
        BufferedImage imgTemp = EnigmaUtils.ImageLoader.loadImage("./images/ac-blackball-jump.png");
        for (int i=0;i<5;i++){
            jumpImgs[i] = imgTemp.getSubimage(0, i*40, 40, 40);
        }
    }

    @Override
    protected double[] getImpulse(){
        double[] impulse=manager.getPlateImpulse(this);
        double[] userImpulse=manager.getUserImpulse();
        impulse[0]=impulse[0]+userImpulse[0]*userImpulseFactor;
        impulse[1]=impulse[1]+userImpulse[1]*userImpulseFactor;
        return impulse;
    }

    public void setUserImpulseFactor(double factor){
        userImpulseFactor=factor;
    }

    public void allowUserControl(boolean b){
        if (b){
            setUserImpulseFactor(1);
            jumpEnabled=true;
        }
        else{
            setUserImpulseFactor(0);
            jumpEnabled=false;
        }
    }

    public void drown() {
        if (jumping <=0){
            died();
        }
    }

    public void invincibleFor(long time){
        if (jumping <= 0){//Pas de saut pendant l'invincibilité
            invincibility=time;
            imageBackup=image;
        }
    }

    public void jump(){
        if (jumpEnabled && jumping<=0 && invincibility <=0){//n'est pas en train de sauter ni n'est invincible
            System.out.println("jumping");
            jumping=jumpingTime;
            currentJumpingImg=0;
            imageBackup=image;
            setFriction(1);
            setUserImpulseFactor(0);
            setFrictionModifiable(false);
        }
    }

    @Override
    public boolean updateImage(long dtime){
        boolean updated = false;
        if (invincibility>0){
            BufferedImage imageTemp=new BufferedImage(40,40,BufferedImage.TYPE_INT_ARGB);
            Graphics buffer = imageTemp.getGraphics();
            buffer.drawImage(imageBackup, 0, 0, null);
            invincibility-=dtime;
            if (invincibility>3000)
                buffer.drawImage(invincibleImgs[0], 0, 0, null);
            else {//Reste moins de 3 secondes: Clignotement
                if (invincibility%400>200)
                    buffer.drawImage(invincibleImgs[1], 0, 0, null);
                else
                    buffer.drawImage(invincibleImgs[2], 0, 0, null);
            }
            image=imageTemp;
            updated=true;
        }
        else if (jumping>0){
            jumping-=dtime;
            if (jumping<=jumpingTime-currentJumpingImg*timeByJumpingImg){
                currentJumpingImg++;
                updated=true;
                //System.out.println("jumping updated. jumping: "+jumping+" currentJumpingImg: "+currentJumpingImg);
            }
            if (currentJumpingImg<5)
                image=jumpImgs[currentJumpingImg-1];//currentJumpingImg initialisé à 0 puis passe à 1 avec le IF precedent
            else if (currentJumpingImg>=5)
                image=jumpImgs[9-currentJumpingImg];//voir fichier image -> on repart dans l'autre sens
        }
        else if (imageBackup != null){//Fin invincibility ou jumping
            System.out.println("fin actor anim");
            image=imageBackup;
            imageBackup=null;
            setFrictionModifiable(true);
            //Le floor space met le facteur à 0 aussi -> En cas d'atterrissage
            //sur un floor space, laisse l'impulse factor à 0
            if(jumpEnabled)
                setUserImpulseFactor(1);
            updated=true;
        }
        return updated;
    }

    public void killed() {
        died();
    }

    public void explode() {
        died();
    }

    public void died(){
        if(invincibility<=0){
            super.died();
            try {
                this.finalize();
            } catch (Throwable ex) {
            }
        }
    }

    public void addDx(double dx) {
        if (jumping<=0)
            this.dx+=dx;
    }

    public void addDy(double dy) {
        if (jumping<=0)
            this.dy+=dy;
    }
}
